<template>
  <div class="ma-content-block lg:flex justify-between p-4">
    <a-spin :loading="spinLoading" :tip="spinTip" dot style="width: 100%;">
      <a-layout-content class="flex flex-col lg:h-full relative w-full">
        <div ref="searchRef">

        </div>
        <div class="table-content">
          <div class="table-header lg:flex justify-between mb-2">
            <a-space class="lg:flex block lg:inline-block">
              <a-button v-if="!exportStatus" type="primary" status="warning" @click="batchExport()">
                <template #icon><icon-play-circle /></template>备份
              </a-button>
              <a-button v-else type="primary" status="warning" @click="batchExport()">
                备份完成，点击重新备份
              </a-button>
              <a-button status="success" @click="batchOptimize()">优化表</a-button>
              <a-button type="dashed" status="success" @click="batchRepair()">修复表</a-button>
            </a-space>
            <a-space class="lg:mt-0 mt-2">
              <a-tooltip content="刷新表格"><a-button shape="circle" @click="refresh()"><icon-refresh /></a-button></a-tooltip>
              <a-tooltip content="设置"><a-button shape="circle" @click="setTableColumns()"><icon-settings /></a-button></a-tooltip>
            </a-space>
          </div>
          <div ref="tableContainerRef">
            <a-table
              ref="tableRef"
              row-key="name"
              :loading="loading"
              :pagination="false"
              :data="renderData"
              :bordered="{ wrapper: true, cell: true }"
              :row-selection="rowSelection"
              :scroll="tableScroll"
              column-resizable
              @selection-change="selectionChange"
            >
              <template #columns>
                <vue-table-column :columns="columns">
                  <template #name="{ record }">
                    <a-link @click="view(record)">
                      {{ record.name }}
                    </a-link>
                  </template>
                  <template #status="{ record }">
                    <a-tag :class="`btn--${record.Name}`" color="">未备份</a-tag>
                  </template>
                  <template #operations="{ record }">
                    <a-space>
                      <a-button type="primary" size="small" @click="optimize([record])">优化表</a-button>
                      <a-button type="primary" status="warning" size="small" @click="repair([record])">修复表</a-button>
                    </a-space>
                  </template>
                </vue-table-column>
              </template>
            </a-table>
          </div>
        </div>
      </a-layout-content>
    </a-spin>

    <SetColumn ref="setColumnRef" :columns="columns" @update:columns="updateColumns"/>

    <View ref="viewRef"/>
  </div>
</template>

<script setup>
  import { ref, reactive, h, compile, nextTick, onMounted, onUnmounted } from 'vue';
  import { Message, Modal } from '@arco-design/web-vue';

  import useLoading from '@/hooks/loading';
  import { workAreaHeight } from '@/utils/index';
  import tool from '@/utils/tool';
  import { apiExportList, apiExport, apiOptimize, apiRepair } from '@/api/database';
  import VueTableColumn from '@/components/table/table-column.vue';
  import SetColumn from '@/components/table/set-column.vue';
  import View from './components/view.vue';

  const { loading, setLoading } = useLoading(false);
  const baseColumns = [
    {
      title: '序号', dataIndex: 'id', width: 70,
      align: 'center', fixed: 'left',
    },
    {
      title: '表名', dataIndex: 'name', width: 200,
      align: 'center',
      slotName: 'name',
    },
    {
      title: '表索引', dataIndex: 'engine',  width: 100,
      align: 'center',
    },
    {
      title: '数据量', dataIndex: 'rows',  width: 100,
      align: 'center',
    },
    {
      title: '数据大小', dataIndex: 'data_length',  width: 100,
      align: 'center',
    },
    {
      title: '碎片大小', dataIndex: 'data_free',  width: 100,
      align: 'center',
    },
    {
      title: '索引大小', dataIndex: 'index_length',  width: 100,
      align: 'center',
    },
    {
      title: '编码', dataIndex: 'collation',  width: 170,
      align: 'center',
    },
    {
      title: '创建时间', dataIndex: 'create_time', width: 180,
      align: 'center',
    },
    {
      title: '说明', dataIndex: 'comment',  width: 160,
      align: 'center',
    },
    {
      title: '状态', dataIndex: 'status',  width: 120,
      align: 'center',
      slotName: 'status',
    },
    {
      title: '操作', dataIndex: 'operations', width: 180,
      align: 'center', fixed: 'right',
      slotName: 'operations',
    },
  ];
  const columns = ref(tool.local.get('columns-database-export') || baseColumns);
  const renderData = ref([]);
  const rowSelection = reactive({
    type: 'checkbox',
    selectedRowKeys: [],
    showCheckedAll: true,
  });
  const tableScroll = ref({
    x: '100%',
    y: '100%',
  });

  const searchRef = ref();
  const showSearch = ref(true);
  const tableContainerRef = ref();
  const tableRef = ref();
  const setColumnRef = ref();
  const searchHeight = ref(0);

  const isReset = ref(true); // 是否重置
  let selectionKeys = []; // 选中项ID
  const spinLoading = ref(false);
  const spinTip = ref();
  const viewRef = ref();
  const exportStatus = ref(false);

  const settingFixedPage = () => {
    const workHeight = workAreaHeight(100);
    const tableHeight = workHeight - searchHeight.value;
    tableContainerRef.value.style.height = `${tableHeight}px`;
  };
  const resizeHandler = () => {
    searchHeight.value = searchRef.value.offsetHeight;
    settingFixedPage();
  };
  const toggleSearch = async () => {
    const dom = searchRef.value?.style;
    if (dom) {
      showSearch.value = !showSearch.value;
      await nextTick(() => {
        searchHeight.value = searchRef.value.offsetHeight;
        settingFixedPage();
      });
    }
  };
  const setTableColumns = () => {
    setColumnRef.value.init();
  };
  const updateColumns = (data) => {
    columns.value = data;
    tool.local.set('columns-database-export', columns.value);
  };

  // 列表
  const fetchData = async (
    params = {}
  ) => {
    setLoading(true);
    await reset();
    try {
      const { data } = await apiExportList(params);
      renderData.value = data.data;
      // you can report use errorHandler or other
    } finally {
      setLoading(false);
    }
  };
  // 备份
  const doExport = (row) => {
    const title = '备份表';
    const message = `确定要备份选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
    const tables = row;
    Modal.warning({
      title,
      content: () => h('div', { innerHTML: message }),
      closable: true,
      hideCancel: false,
      onOk: (async () => {
        setLoading(true);
        await apiExport({
          tables,
        }).then(res => {
          backup(res.data, row);
        }).catch(() => {
          setLoading(false);
        });

        window.onbeforeunload = function () {
          return '正在备份数据库，请不要关闭！';
        }
      }),
    });
  };
  // 优化表
  const optimize = (row) => {
    let title = '优化表';
    let message = `确定要优化选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
    let tables = row;
    if (row.length === 1 && row[0].name) {
      title = `${title}：${row[0].name}`;
      message = `确定要优化表名 <span style="color:red">${row[0].name} </span> 这条数据吗？`;
      tables = [row[0].name];
    }
    Modal.warning({
      title,
      content: () => h('div', { innerHTML: message }),
      closable: true,
      hideCancel: false,
      onOk: (async () => {
        setLoading(true);
        try {
          const res = await apiOptimize({tables});
          if (res.status === 1) {
            Message.success(res.msg);
          }
        } catch (err) {
          setLoading(false);
        } finally {
          setLoading(false);
        }
      }),
    });
  };
  // 修复表
  const repair = (row) => {
    let title = '修复表';
    let message = `确定要修复选中的 <span style="color:red">${row.length} </span> 条数据吗？`;
    let tables = row;
    if (row.length === 1 && row[0].name) {
      title = `${title}：${row[0].name}`;
      message = `确定要修复表名 <span style="color:red">${row[0].name} </span> 这条数据吗？`;
      tables = [row[0].name];
    }
    Modal.warning({
      title,
      content: () => h('div', { innerHTML: message }),
      closable: true,
      hideCancel: false,
      onOk: (async () => {
        setLoading(true);
        try {
          const res = await apiRepair({tables});
          if (res.status === 1) {
            Message.success(res.msg);
          }
        } catch (err) {
          setLoading(false);
        } finally {
          setLoading(false);
        }
      }),
    });
  };
  // 备份
  const backup = async (data, row) => {
    // 开始备份
    if (data.status === 1) {
      document.getElementsByClassName(`btn--${data.tab.name}`)[0].innerHTML = '开始备份...(0%)';
      document.getElementsByClassName(`btn--${data.tab.name}`)[0].setAttribute('style', 'color: #ffffff; background-color: #86909c');
      await apiExport({
        id: data.tab.id,
        start: data.tab.start,
      }).then(res2 => {
        document.getElementsByClassName(`btn--${data.tab.name}`)[0].innerHTML = res2.data.info;
        document.getElementsByClassName(`btn--${data.tab.name}`)[0].setAttribute('style', 'color: #ffffff; background-color: #7bc616');
        if (res2.data.tab) {
          backup(res2.data, row);
        } else {
          exportStatus.value = true;
          setLoading(false);
          window.onbeforeunload = function () {
            return null;
          }
        }
      }).catch(() => {
        setLoading(false);
      });
    }
  };
  // 查看
  const view = async (row) => {
    viewRef.value.fetchData(row);
  };
  // 重置
  const reset = async () => {
    if (isReset.value) {
      rowSelection.selectedRowKeys = [];
      selectionKeys = [];
    } else {
      isReset.value = true;
    }
  };
  // 刷新
  const refresh = async () => {
    await fetchData();
  };

  // 已选择的数据行发生改变时触发 -- table 表头
  const selectionChange = (rowKeys) => {
    rowSelection.selectedRowKeys = rowKeys;
    selectionKeys = rowKeys;
  };
  const selectMsg = (message) => {
    Message.info(message || '请选择需要操作的数据');
  };
  // 批量备份表
  const batchExport = () => {
    if (!selectionKeys.length) {
      selectMsg();
    } else {
      doExport(selectionKeys);
    }
  };
  // 批量优化表
  const batchOptimize = () => {
    if (!selectionKeys.length) {
      selectMsg();
    } else {
      optimize(selectionKeys);
    }
  };
  // 批量修复表
  const batchRepair = () => {
    if (!selectionKeys.length) {
      selectMsg();
    } else {
      repair(selectionKeys);
    }
  };

  onMounted(async () => {
    await fetchData();
    window.addEventListener('resize', resizeHandler, false);
    searchHeight.value = searchRef.value.offsetHeight;
    settingFixedPage();
  });
  onUnmounted(() => {
    window.removeEventListener('resize', resizeHandler, false);
  });
</script>

<script>
  export default {
    name: 'DatabaseExport',
  };
</script>

<style scoped lang="less">

</style>
